/**
 * 
 */
package com.googlecode.cswish;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.servlet.ServletContext;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.googlecode.cswish.struts.BaseActionSupport;
import com.googlecode.cswish.struts.ContextHolder;
import com.googlecode.cswish.struts.spring.ObjectFactory;
import com.googlecode.cswish.struts.spring.SystemEnv;
import com.opensymphony.xwork2.ActionContext;

/**
 * Get the configuration of web project environment
 * 
 * @author Jerry.Feng Date: 2008-4-3
 *
 */
public class Config {	
	private final static Logger logger = Logger.getLogger(Config.class);
	
	private final String[] BLANK_STRINGS = new String[] {""};
	
	private static Config instance;

	private String realWebRootPath;
	
	/**
	 * the directory of jsp/ftl/vm file
	 */
	private String viewDir = "/pages/";
	
	/**
	 * the directory of view file which is created by system according to the PageElements
	 */
	private String viewDir4GenCode = "/pagesGen/";
	
	/**
	 * page template directory
	 */
	private String templateDir = "/decorators/";
	
	/**
	 * the template directory to display default view template
	 * different template has different style, such as facebook style, amazon style etc
	 */
	private String commonViewPkg = "/view/";
	
	/**
	 * CSS directory
	 */
	private String cssDir = "/css/default/";
	
	/**
	 * Image directory
	 */
	private String imgDir = "/images/default/";
	
	private String imgTagDir = "/images/tag/";
	
	private String uploadDir = "/upload/";
		
	// DB备份文件目录
	private String backupDir = "/";
	
	private String javaSourceDir = "/javatmp/";
	
	// 工作流的存储目录
	private String bpmn = "/WEB-INF/bpmn/";
	
	private boolean devMode;
	
	///////////////////////////////// pagination //////////////////////////////
	private int pageSize = 30;	// default value
	
	///////////////////////////////// actionSupport ////////////////////////////////
	// see ActionFactoryBean.
	private Class baseAction = BaseActionSupport.class;
	private boolean enableGenCode = true;
	private Properties beanNames;
	
	///////////////////////////////// display /////////////////////////////////
	private String dataFormat = "yyyy-MM-dd";
	private String detailDataFormat = "yyyy-MM-dd HH:mm:ss";
	
	///////////////////////////////// security ////////////////////////////////
	/**
	 * enable security check
	 */
	private boolean securityEnable;
	private String securityFreePath = "/$/";
	private String securityforbidPath = "/view/";
	private String securityWarningPage = "/$/login/warning.execute";
	private String securityLoginPage = "/$/login/login.execute";
	// enable to validate user info from windows domain
	private String securityDomain;
	
	//////////////////////////////// module setting ////////////////////////////
	// default language
	private String language;
	private String host;
	private String mailFrom;
	private String version = "1.0";
	
	private boolean enableSaas;

	public Config() {
		beanNames = new Properties();
		InputStream input = null;
		try {
			input = this.getClass().getResourceAsStream("/cswish-bean.properties");
			beanNames.load(input);
		} catch (IOException ex) {
			logger.error("Failed to parse the properties", ex);
		} finally {
			IOUtils.closeQuietly(input);
		}
		instance = this; 
	}
	
	public static Config getInstance() {
		if (instance == null) {
			instance = ObjectFactory.getInstance().getBean(Config.class, false);
		}
		return instance;
	}
	
	public String getRealWebRootPath() {
		if (realWebRootPath == null) {
			ActionContext context = ActionContext.getContext();
			if (context != null) {
				ServletContext servletContext = (ServletContext) context.get(ServletActionContext.SERVLET_CONTEXT);
				if (servletContext != null) {
					realWebRootPath = servletContext.getRealPath("/");
				}
			}

			if (realWebRootPath == null) {
				String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
				int index = path.lastIndexOf("/WEB-INF/");
				boolean isEclipseEnv = index == -1;
				if (isEclipseEnv) {
					String projectHome = System.getProperty(SystemEnv.PROJECT_HOME);
					realWebRootPath = projectHome + "/src/main/webapp/";
				} else {
					realWebRootPath = path.substring(0, index + 1);
				}
			}
			
			realWebRootPath = new File(realWebRootPath).getPath();
		}
		return realWebRootPath;
	}

	public void setRealWebRootPath(String rootPath) {
		this.realWebRootPath = rootPath;
	}
	
	public String getSitePath() {
		return "/site/" + ContextHolder.get().getSiteName();
	}
	
	public String getRealSitePath() {
		return getRealWebRootPath() + "/site/" + ContextHolder.get().getSiteName();
	}
	
	public String getRealSiteTmpPath() {
		return getRealWebRootPath() + "/site/" + ContextHolder.get().getSiteName() + "/tmp";
	}
	
	public String getRealSiteTmpPath(String subDir) {
		return getRealWebRootPath() + "/site/" + ContextHolder.get().getSiteName() + "/tmp/" + subDir;
	}

	public String getRealSitePath(String siteName) {
		return getRealWebRootPath() + "/site/" + siteName;
	}
	
	public String getViewDir() {
		return viewDir;
	}

	public void setViewDir(String viewDir) {
		this.viewDir = formatDir(viewDir, '/');
	}
	
	public String getViewDir4GenCode() {
		return viewDir4GenCode;
	}

	public void setViewDir4GenCode(String viewDir4GenCode) {
		this.viewDir4GenCode = formatDir(viewDir4GenCode, '/');
	}

	public String getCommonViewPkg() {
		return commonViewPkg;
	}

	public void setCommonViewPkg(String templateDir) {
		this.commonViewPkg = formatDir(templateDir, '/');
	}
	
	public String getTemplateDir() {
		return templateDir;
	}

	public void setTemplateDir(String templateDir) {
		this.templateDir = templateDir;
	}

	public String getUploadDir() {
        return uploadDir;
    }

    public void setUploadDir(String photoWeb) {
        this.uploadDir = photoWeb;
    }
	
	public String getCssDir() {
		return cssDir;
	}

	public void setCssDir(String cssDir) {
		this.cssDir = formatDir(cssDir, '/');
	}
	
	private String formatDir(String dir, char sep) {
		int len = dir.length();
		StringBuilder sb = new StringBuilder(len + 1);
		char lastC = '?';
		for (int i = 0; i < len; i++) {
			char c = dir.charAt(i);
			if (c == sep) {
				if (lastC == sep) {
					// it's duplicated separator, skip it
				} else {
					sb.append(c);
				}
			} else {
				sb.append(c);
			}
			lastC = c;
		}
		if (sb.charAt(sb.length() - 1) != sep) {
			sb.append(sep);
		}
		return sb.toString();
		
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public boolean isSecurityEnable() {
		return securityEnable;
	}

	public void setSecurityEnable(boolean securityEnable) {
		this.securityEnable = securityEnable;
	}

	public String getSecurityFreePath() {
		return securityFreePath;
	}

	public void setSecurityFreePath(String securityFreePath) {
		this.securityFreePath = securityFreePath;
	}

	public String getSecurityforbidPath() {
		return securityforbidPath;
	}

	public void setSecurityforbidPath(String securityforbidPath) {
		this.securityforbidPath = securityforbidPath;
	}

	public String getSecurityWarningPage() {
		return securityWarningPage;
	}

	public void setSecurityWarningPage(String securityWarningPage) {
		this.securityWarningPage = securityWarningPage;
	}

	public String getSecurityLoginPage() {
		return securityLoginPage;
	}

	public void setSecurityLoginPage(String securityLoginPage) {
		this.securityLoginPage = securityLoginPage;
	}

	public boolean isEnableGenCode() {
		return enableGenCode;
	}

	public void setEnableGenCode(boolean enableGenCode) {
		this.enableGenCode = enableGenCode;
	}
	
	public String getClassImplName(String className) {
		return beanNames.getProperty(className);
	}

	public Class getBaseAction() {
		return baseAction;
	}

	public void setBaseAction(Class baseAction) {
		this.baseAction = baseAction;
	}

	public String getDataFormat() {
		return dataFormat;
	}

	public void setDataFormat(String dataFormat) {
		this.dataFormat = dataFormat;
	}
	
	public String getDetailDataFormat() {
		return detailDataFormat;
	}

	public void setDetailDataFormat(String detailDataFormat) {
		this.detailDataFormat = detailDataFormat;
	}

	public String getImgDir() {
		return imgDir;
	}

	public void setImgDir(String imgDir) {
		this.imgDir = imgDir;
	}

	public String getImgTagDir() {
		return imgTagDir;
	}

	public void setImgTagDir(String imgTagDir) {
		this.imgTagDir = imgTagDir;
	}

	public String getSecurityDomain() {
		return securityDomain;
	}

	public void setSecurityDomain(String securityDomain) {
		this.securityDomain = securityDomain;
	}

	@Override
	public String toString() {
		return "cssDir=" + getCssDir() + '\n'
				+ "imgDir=" + getImgDir() + '\n'
				+ "viewDir=" + getViewDir() + '\n'
				+ "viewTemplate=" + getCommonViewPkg() + '\n'
				
				+ "securityEnable=" + isSecurityEnable() + '\n'
				+ "securityFreePath=" + getSecurityFreePath() + '\n'
				+ "securityforbidPath=" + getSecurityforbidPath() + '\n'
				+ "securityLoginPage=" + getSecurityLoginPage() + '\n'
				+ "securityLoginPage=" + getSecurityLoginPage() + '\n'
		;
	}

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
		this.language = language;
	}

	public boolean isDevMode() {
		return devMode;
	}

	public void setDevMode(boolean devMode) {
		this.devMode = devMode;
	}

	public String getMailFrom() {
		return mailFrom;
	}

	public void setMailFrom(String mailFrom) {
		this.mailFrom = mailFrom;
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}
	
	public String getBackupDir() {
		return backupDir;
	}

	public void setBackupDir(String backupDir) {
		this.backupDir = formatDir(backupDir, '/');
	}
	
	public void setJavaSourceDir(String javaSourceDir) {
		this.javaSourceDir = javaSourceDir;
	}

	public String getJavaSourceDir() {
		return javaSourceDir;
	}
	
	public String getBpmn() {
		return bpmn;
	}

	public void setBpmn(String bpmn) {
		this.bpmn = bpmn;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public String getPluginDir(String site) {
		// Only the eclipse environment has the public/private definition
		if ("true".equals(System.getProperty(SystemEnv.RUNNING_IN_ECLIPSE))) {
			String privateSiteDir = getRealWebRootPath() + "/WEB-INF/plugins/" + site + '/';
			if (new File(privateSiteDir).exists()) {
				return privateSiteDir;
			}
		}
		
		String publicSiteDir = System.getProperty(SystemEnv.PLUGIN_HOME) + '/' + site + '/';
		return publicSiteDir;
	}

	public boolean isFreeResource(String path) {
		return path.startsWith(getSecurityFreePath());
	}

	public boolean isEnableSaas() {
		return enableSaas;
	}

	public void setEnableSaas(boolean enableSaas) {
		this.enableSaas = enableSaas;
	}
	
	public boolean isEnableSitePath() {
		return enableSaas;
		//return true;
	}
}